package com.reebake.ideal.security.handler;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.reebake.ideal.cache.helper.TimesCacheHelper;
import com.reebake.ideal.security.core.LoginFailureEvent;
import com.reebake.ideal.security.core.LoginSuccessEvent;
import com.reebake.ideal.security.core.SecurityConstants;
import com.reebake.ideal.security.entity.UserLoginLogEntity;
import com.reebake.ideal.security.properties.ServerSecurityProperties;
import com.reebake.ideal.security.service.UserSecurityService;
import com.reebake.ideal.servlet.util.WebUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.http.HttpHeaders;

public class LoginAuthenticationEventHandler {
    @Autowired
    private UserSecurityService userSecurityService;
    @Autowired
    private ServerSecurityProperties serverSecurityProperties;
    public final static String LOGIN_FAILURE_TIMES = "login:failure:times:";
    private final TimesCacheHelper timesCacheHelper = new TimesCacheHelper(LOGIN_FAILURE_TIMES, 0);

    @EventListener
    public void loginFailureEvent(LoginFailureEvent loginFailureEvent) {
        String username = loginFailureEvent.getUsername();
        long times = timesCacheHelper.getTimes(username);
        Integer maxLoginTryTimes = serverSecurityProperties.getMaxLoginTryTimes();

        if(maxLoginTryTimes > 0) {
            if (times >= maxLoginTryTimes) {
                userSecurityService.lock(username);
            }else {
                timesCacheHelper.increase(username);
            }
        }
    }

    @EventListener
    public void loginSuccessEvent(LoginSuccessEvent loginSuccessEvent) {
        String username = loginSuccessEvent.getUsername();
        String userId = loginSuccessEvent.getUserId();
        String source = loginSuccessEvent.getFrom();
        String ip = WebUtil.getClientIP();
        UserLoginLogEntity userLoginLogEntity = new UserLoginLogEntity();
        userLoginLogEntity.setLoginIp(ip);
        userLoginLogEntity.setLoginTime(DateUtil.date());
        userLoginLogEntity.setLoginName(username);
        HttpServletRequest request = WebUtil.getRequest();
        UserAgent userAgent = UserAgentUtil.parse(request.getHeader(HttpHeaders.USER_AGENT));
        userLoginLogEntity.setSource(source);
        userLoginLogEntity.setBrowserName(userAgent.getBrowser().getName());
        userLoginLogEntity.setBrowserVersion(userAgent.getVersion());
        userLoginLogEntity.setOsName(userAgent.getOs().getName());
        userLoginLogEntity.setOsVersion(userAgent.getOsVersion());
        userLoginLogEntity.setDeviceId(request.getHeader(SecurityConstants.HEADER_NAME_DEVICE_ID));

        userLoginLogEntity.setUserId(userId);

        userSecurityService.log(userLoginLogEntity);
    }
}
